#ifndef DESC_H
#define DESC_H

#include "utility/Types.h"
#include "Const.h"

#pragma pack(1)

/// @brief 段描述符结构体
typedef struct SegmentDesc
{
    uint16_t limitLow; // 段界限
    uint16_t baseLow;  // 段基址
    uint8_t baseMid;   // 段基址
    // 0-3:Type, 4:S, 5-6:DPL, 7:P, 8-11:Limit 12:AVL 13:L 14:D/B 15:G
    uint16_t attr;     // 属性
    uint8_t baseHigh;  // 段基址
} SegmentDescType;

typedef struct GateDesc
{
    uint16_t offsetLow;
    uint16_t gdtSelector;
    // 15:P, 13-14:DPL, 11: D, 8-10: Type
    uint16_t attr;
    uint16_t offsetHigh;
} GateDescType;

/// @brief Task state segment
typedef struct TssDesc
{
    uint32_t preLink;
    uint32_t esp0, ss0, esp1, ss1, esp2, ss2;
    // PDE table address
    uint32_t cr3;
    uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
    uint32_t es, cs, ss, ds, fs, gs;
    uint32_t ldt;
    // point to i/o bitmap
    uint32_t iomap;
} TssDescType;

#pragma pack()


void SetGDTSegmentDesc(int index, uint32_t base, uint32_t limit, uint16_t attr);
void InitGDT();
void SetIDTGateDesc(int index, uint16_t selector, uint32_t offset, uint16_t attr);
void InitIDT();
void InitTable();

uint32_t AllocGdtDesc(void);
uint32_t FreeGDTSelector(int selector);

#endif
